﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace THenu.TinyHourseLib.DesignPattern.Singleton_Pattern
{
    /// <summary>
    /// 私有化构造实现的单例
    /// </summary>
    public class PrivateConstruct
    {
        /// <summary>
        /// 声明全局可用的静态成员
        /// </summary>
        private static PrivateConstruct _Instance = null;
        /// <summary>
        /// 私有化构造器阻止类外实例化
        /// </summary>
        private PrivateConstruct() { }
        /// <summary>
        /// 延迟到首次使用创建 =》避免了在应用程序启动时实例化不必要的 singleton
        /// </summary>
        public static PrivateConstruct Instance
        {
            get
            {
                // 当然多线程下是不能保证单例的
                if (_Instance == null)
                    _Instance = new PrivateConstruct();

                return _Instance;
            }
        }

    }

    /// <summary>
    ///  利用锁定实现线程安全 Locking 
    /// </summary>
    public class SafeSingleton
    {
        /// <summary>
        /// 锁定单元
        /// </summary>
        private static object objLock = new object();
        /// <summary>
        /// 唯一静态实例成员
        /// </summary>
        private static volatile SafeSingleton _Instance = null;
        /// <summary>
        /// 私有化构造器阻止类外实例化
        /// </summary>
        private SafeSingleton() { }
        /// <summary>
        /// 延迟到首次使用创建 =》避免了在应用程序启动时实例化不必要的 singleton
        /// </summary>
        public static SafeSingleton Instance
        {
            get
            {
                // 进去安全区将执行锁定,即没一次访问都会造成锁定
                lock (objLock)
                {
                    if (_Instance == null)
                        _Instance = new SafeSingleton();


                    return _Instance;
                }
            }
        }

    }
    /// <summary>
    /// 双重检查的锁定单例  Double-Check Locking
    /// </summary>
    public class DoubleCheckSingleton
    {
        /// <summary>
        /// 锁定单元 使用 syncRoot 实例来进行锁定（而不是锁定类型本身），以避免发生死锁。
        /// </summary>
        private static object objLock = new object();
        /// <summary>
        /// 唯一静态实例成员
        /// </summary>
        private static volatile DoubleCheckSingleton _Instance = null;
        /// <summary>
        /// 私有化构造器阻止类外实例化
        /// </summary>
        private DoubleCheckSingleton() { }
        /// <summary>
        /// 延迟到首次使用创建 =》避免了在应用程序启动时实例化不必要的 singleton
        /// </summary>
        public static DoubleCheckSingleton Instance
        {
            get
            {
                // 未创建时进入锁定的访问区
                if (_Instance == null)
                {
                    // 进去安全区将执行锁定 
                    lock (objLock)
                    {
                        if (_Instance == null)
                            _Instance = new DoubleCheckSingleton();

                    }
                }
                return _Instance;

            }
        }

    }
}
